package com.taxx.excel.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.taxx.entity.TaxIncomeReport;
import com.taxx.enums.ReportStatusEnums;
import com.taxx.excel.IncomeExcelData;
import com.taxx.service.TaxIncomeReportService;
import com.taxx.util.DateUtil;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

/**
 * 收入信息Excel导入监听器
 *
 * @author taxx
 * @since 2024-01-01
 */
@Slf4j
public class IncomeExcelListener extends AnalysisEventListener<IncomeExcelData> {

    /**
     * -- SETTER --
     * 设置税务收入报告服务
     */
    @Setter
    private TaxIncomeReportService taxIncomeReportService;

    /**
     * 数据列表
     */
    private final List<TaxIncomeReport> dataList = new ArrayList<>();

    /**
     * 成功数量
     */
    private int successCount = 0;

    /**
     * 失败数量
     */
    private int failCount = 0;

    /**
     * 错误信息列表
     */
    private final List<String> errorMessages = new ArrayList<>();

    // 时间参数字段
    private String startTime;
    private String endTime;

    @Override
    public void invoke(IncomeExcelData data, AnalysisContext context) {
        try {
            // 必填字段校验
            String errorStr = validateRequiredFields(data);
            if (errorStr != null && !errorStr.isEmpty()) {
                failCount++;
                errorMessages.add(errorStr);
            } else {
                TaxIncomeReport report = convertToEntity(data);
                dataList.add(report);
                successCount++;
            }
        } catch (Exception e) {
            failCount++;
            String errorMsg = "第" + (context.readRowHolder().getRowIndex() + 1) + "行数据转换失败：" + e.getMessage();
            errorMessages.add(errorMsg);
            log.error(errorMsg, e);
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        try {
            if (!dataList.isEmpty()) {
                taxIncomeReportService.saveBatch(dataList);
                log.info("收入信息Excel导入完成，成功导入{}条，失败{}条", successCount, failCount);
            }
        } catch (Exception e) {
            log.error("批量保存收入信息失败", e);
            failCount += successCount;
            successCount = 0;
            errorMessages.add("批量保存失败：" + e.getMessage());
        }
        // 注意：不在这里清理数据，等getImportResult()被调用后再清理
    }

    /**
     * 清理数据，避免累积
     */
    public void clearData() {
        dataList.clear();
        successCount = 0;
        failCount = 0;
        errorMessages.clear();
        log.debug("收入信息监听器数据已清理");
    }

    /**
     * 设置时间参数
     */
    public void setTimeParams(String startTime, String endTime) {
        this.startTime = startTime;
        this.endTime = endTime;
    }

    /**
     * 转换为实体对象
     */
    private TaxIncomeReport convertToEntity(IncomeExcelData data) {


        TaxIncomeReport report = new TaxIncomeReport();

        // 设置基本信息
        report.setHasRegistration("Y".equals(data.getHasRegistration()) ? 1 : 0);
        report.setCreditCode(data.getCreditCode());
        report.setTaxpayerName(data.getTaxpayerName());
        report.setMerchantId(data.getMerchantId());
        report.setMerchantName(data.getMerchantName());

        // 设置收入信息
        report.setGoodsIncome(parseBigDecimal(data.getGoodsIncome()));
        report.setGoodsRefund(parseBigDecimal(data.getGoodsRefund()));
        report.setIntangibleIncome(parseBigDecimal(data.getIntangibleIncome()));
        report.setIntangibleRefund(parseBigDecimal(data.getIntangibleRefund()));
        report.setServiceIncome(parseBigDecimal(data.getServiceIncome()));
        report.setServiceRefund(parseBigDecimal(data.getServiceRefund()));
        report.setUnregisteredIncome(parseBigDecimal(data.getUnregisteredIncome()));
        report.setUnregisteredRefund(parseBigDecimal(data.getUnregisteredRefund()));
        report.setNetIncomeGoods(parseBigDecimal(data.getNetIncomeGoods()));
        report.setNetIncomeTransport(parseBigDecimal(data.getNetIncomeTransport()));
        report.setNetIncomeLabor(parseBigDecimal(data.getNetIncomeLabor()));
        report.setNetIncomeRoyalty(parseBigDecimal(data.getNetIncomeRoyalty()));
        report.setNetIncomeFranchise(parseBigDecimal(data.getNetIncomeFranchise()));
        report.setOtherNetIncome(parseBigDecimal(data.getOtherNetIncome()));
        report.setPlatformCommission(parseBigDecimal(data.getPlatformCommission()));
        report.setTransactionCount(parseInteger(data.getTransactionCount()));

        // 设置时间参数
        report.setStartTime(this.startTime);
        report.setEndTime(this.endTime);
        report.setBatchCode(DateUtil.formatDate(LocalDate.now(), "yyyyMMdd"));

        // 设置默认值
        report.setReportStatus(ReportStatusEnums.WAIT_SUBMIT.getCode()); // 待报送

        return report;
    }

    /**
     * 必填字段校验
     */
    private String validateRequiredFields(IncomeExcelData data) {
        List<String> errors = new ArrayList<>();

        // 校验纳税人名称
        if (data.getTaxpayerName() == null || data.getTaxpayerName().trim().isEmpty()) {
            errors.add(data.getMerchantName() + "纳税人名称不能为空");
        }

        // 校验统一社会信用代码
        if (data.getCreditCode() == null || data.getCreditCode().trim().isEmpty()) {
            errors.add(data.getMerchantName() + "统一社会信用代码不能为空");
        }

        // 校验商户ID
        if (data.getMerchantId() == null || data.getMerchantId().trim().isEmpty()) {
            errors.add(data.getMerchantName() + "商户ID不能为空");
        }

        // 校验商户名称
        if (data.getMerchantName() == null || data.getMerchantName().trim().isEmpty()) {
            errors.add(data.getCreditCode() + "商户名称不能为空");
        }

        // 校验是否办理市场主体登记
        if (data.getHasRegistration() == null || data.getHasRegistration().trim().isEmpty()) {
            errors.add(data.getMerchantName() + "是否办理市场主体登记不能为空");
        }

        // 校验时间参数
        if (this.startTime == null || this.startTime.trim().isEmpty()) {
            errors.add(data.getMerchantName() + "收入所属期起时间不能为空");
        }

        if (this.endTime == null || this.endTime.trim().isEmpty()) {
            errors.add(data.getMerchantName() + "收入所属期止时间不能为空");
        }

        boolean isExist = taxIncomeReportService.isExist(data.getCreditCode(), this.startTime, this.endTime, DateUtil.formatDate(LocalDate.now(), "yyyyMMdd"));
        if (isExist) {
            errors.add("当前批次[" + data.getCreditCode() + "]" + data.getMerchantName() + "在数据库中已经存在");
        }
        dataList.forEach(item -> {
            if (item.getCreditCode().equals(data.getCreditCode())) {
                errors.add("当前批次[" + data.getCreditCode() + "]" + data.getMerchantName() + "在当前文件已经存在");
            }
        });
        // 如果有校验错误，抛出异常
        if (!errors.isEmpty()) {
            String errorMsg = "数据校验失败：" + String.join("， ", errors);
            log.error(errorMsg);
            return errorMsg;
        } else {
            return null;
        }
    }

    /**
     * 解析BigDecimal
     */
    private java.math.BigDecimal parseBigDecimal(String value) {
        if (value == null || value.trim().isEmpty()) {
            return java.math.BigDecimal.ZERO;
        }
        try {
            return new java.math.BigDecimal(value.trim());
        } catch (NumberFormatException e) {
            log.warn("无法解析BigDecimal值: '{}'，使用默认值0", value);
            return java.math.BigDecimal.ZERO;
        }
    }

    /**
     * 解析Integer
     */
    private Integer parseInteger(String value) {
        if (value == null || value.trim().isEmpty()) {
            return 0;
        }
        try {
            return Integer.parseInt(value.trim());
        } catch (NumberFormatException e) {
            log.warn("无法解析Integer值: '{}'，使用默认值0", value);
            return 0;
        }
    }

    /**
     * 获取导入结果
     */
    public ImportResult getImportResult() {
        ImportResult result = new ImportResult();
        result.setTotalCount(successCount + failCount);
        result.setSuccessCount(successCount);
        result.setFailCount(failCount);
        result.setErrorMessages(new ArrayList<>(errorMessages)); // 创建副本避免外部修改

        // 获取结果后清理数据，避免累积
        clearData();

        return result;
    }

    /**
     * 导入结果类
     */
    @Setter
    @Getter
    public static class ImportResult {
        private int totalCount;
        private int successCount;
        private int failCount;
        private List<String> errorMessages;
    }
}
